﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Net;
using System.IO;
using System.Text;
using System.Threading;
using System.Xml;

namespace HtmlHelper
{

    public class HtmlDocument2 : Component
    {
        // Fields
        private EventHandler K;
        private ArrayList childElements;
        private string html;
        private HtmlDocumentState state;
        private bool blockTagP;
        private string Q;

        // Events
        public event EventHandler StateChanged;

        // Methods
        public HtmlDocument2(): this("")
        {
        }

        public HtmlDocument2(string htmldocument)
        {
            this.childElements = new ArrayList(10);
            this.html = "";
            this.state = HtmlDocumentState.Ready;
            this.blockTagP = false;
            this.Q = "";
            if ((htmldocument != null) && (htmldocument != ""))
            {
                this.html = htmldocument;
                this.parsehtml();
            }
        }

        private void parsehtml()
        {
            int startIndex = 0;
            int index = 0;
            int num3 = 0;
            int num4 = 0;
            int num5 = 0;
            bool flag = false;
            this.childElements.Clear();
            string str4 = this.html.ToLower();
            if (str4 == "")
            {
                return;
            }
            HtmlElement2 element2 = null;
        Label_0038:
            flag = false;
        Label_003B:
            if (num4 > str4.Length)
            {
                startIndex = -1;
                goto Label_0203;
            }
            startIndex = str4.IndexOf('<', num4);
            if (startIndex < 0)
            {
                goto Label_01FC;
            }
            if ((startIndex + 3) >= str4.Length)
            {
                goto Label_0203;
            }
            string str5 = this.html.Substring(num4, startIndex - num4);
            if ((str5 != "") && (str5.Replace("\n", "").Trim() != ""))
            {
                HtmlElement2 element4 = new HtmlElement2();
                element4.Text = str5;
                element4.Type = XhHtmlElementType.Text;
                if (element2 != null)
                {
                    element2.ChildElements.Add(element4);
                }
                else
                {
                    this.childElements.Add(element4);
                }
            }
            string str2 = str4.Substring(startIndex + 1, 2);
            char[] chArray = str2.ToCharArray(0, 1);
            if ((chArray[0] > ' ') && (chArray[0] != '!'))
            {
                if (chArray[0] == '/')
                {
                    flag = true;
                    startIndex++;
                }
                goto Label_0203;
            }
            num4 = startIndex + 1;
            if (!(str2 == "!-"))
            {
                if (chArray[0] == '!')
                {
                    startIndex = str4.IndexOf('>', num4);
                    if (startIndex >= 0)
                    {
                        num4 = startIndex + 1;
                    }
                    startIndex = 1;
                }
                goto Label_01FC;
            }
        Label_0141:
            index = -1;
            num3 = -1;
            try
            {
                index = str4.IndexOf("-->", (int)(startIndex + 1));
                num3 = str4.IndexOf("<!-", (int)(startIndex + 2));
            }
            catch
            {
            }
            if ((num3 >= 0) && (num3 < index))
            {
                startIndex = index + 3;
                if (index >= 0)
                {
                    goto Label_0141;
                }
            }
            if (index < 0)
            {
                num4 = startIndex + 1;
            }
            else
            {
                HtmlElement2 element5 = new HtmlElement2();
                element5.Type = XhHtmlElementType.Comment;
                element5.Text = this.html.Substring(startIndex, (index - startIndex) + 3);
                if (element2 == null)
                {
                    this.childElements.Add(element5);
                }
                else
                {
                    element2.ChildElements.Add(element5);
                    element5.Parent = element2;
                }
                num4 = index + 3;
                startIndex = 1;
            }
        Label_01FC:
            if (startIndex > 0)
            {
                goto Label_003B;
            }
        Label_0203:
            if (startIndex < 0)
            {
                return;
            }
            string tagName = "";
            string str3 = "";
            index = str4.IndexOf('>', startIndex + 1);
            if (index < 0)
            {
                return;
            }
            tagName = this.html.Substring(startIndex + 1, (index - startIndex) - 1);
            num5 = -1;
            for (int i = 0; i < tagName.Length; i++)
            {
                if (tagName[i] <= ' ')
                {
                    num5 = i;
                    break;
                }
            }
            if (num5 >= 0)
            {
                str3 = tagName.Substring(num5).Trim();
                tagName = tagName.Substring(0, num5).Trim().ToLower();
            }
            else
            {
                tagName = tagName.ToLower();
            }
            if (tagName == "")
            {
                num4 = index + 1;
            }
            else
            {
                HtmlElement2 parent;
                bool flag2 = false;
                if (tagName[tagName.Length - 1] == '/')
                {
                    flag2 = true;
                    tagName = tagName.Substring(0, tagName.Length - 1);
                }
                if (flag)
                {
                    if (((((element2 != null) && (tagName != "")) && ((tagName != "param") && (tagName != "meta"))) && ((tagName != "p") || ((tagName == "p") && this.blockTagP))) && (((((tagName != "area") && (tagName != "base")) && ((tagName != "br") && (tagName != "col"))) && (((tagName != "frame") && (tagName != "img")) && ((tagName != "input") && (tagName != "link")))) && ((((tagName != "meta") && (tagName != "basefont")) && ((tagName != "isindex") && (tagName != "hr"))) && (tagName != "script"))))
                    {
                        parent = element2;
                        do
                        {
                            if (parent.TagName == tagName)
                            {
                                element2 = parent.Parent;
                                break;
                            }
                            parent = parent.Parent;
                            if (parent == null)
                            {
                                element2 = null;
                            }
                        }
                        while (parent != null);
                    }
                }
                else
                {
                    HtmlElement2 element = new HtmlElement2(tagName);
                    element.AttributesHTML = str3;
                    if (!flag2)
                    {
                        if (tagName == "li")
                        {
                            if (element2 != null)
                            {
                                parent = element2;
                                do
                                {
                                    if (parent.TagName == "li")
                                    {
                                        element2 = parent.Parent;
                                        break;
                                    }
                                    if (parent.TagName == "ul")
                                    {
                                        element2 = parent;
                                        break;
                                    }
                                    parent = parent.Parent;
                                }
                                while (parent != null);
                            }
                        }
                        else if ((tagName == "script") && !element.HasAttribute("src"))
                        {
                            startIndex = str4.IndexOf("</script>", (int)(index + 1));
                            if (startIndex >= 0)
                            {
                                HtmlElement2 element6 = new HtmlElement2();
                                element6.Type = XhHtmlElementType.Script;
                                element6.Text = this.html.Substring(index + 1, (startIndex - index) - 1);
                                element.ChildElements.Add(element6);
                                element6.Parent = element;
                                if (element2 == null)
                                {
                                    this.childElements.Add(element);
                                }
                                else
                                {
                                    element2.AppendChild(element);
                                    element.Parent = element2;
                                }
                                num4 = startIndex + 9;
                                goto Label_0038;
                            }
                            HtmlElement2 element7 = new HtmlElement2();
                            element7.Type = XhHtmlElementType.Script;
                            element7.Text = this.html.Substring(index + 1);
                            element.ChildElements.Add(element7);
                            element7.Parent = element;
                            if (element2 == null)
                            {
                                this.childElements.Add(element);
                                return;
                            }
                            element2.ChildElements.Add(element);
                            element.Parent = element2;
                            return;
                        }
                    }
                    parent = null;
                    if (element2 == null)
                    {
                        this.childElements.Add(element);
                    }
                    else
                    {
                        element2.ChildElements.Add(element);
                        element.Parent = element2;
                    }
                    if (((((tagName != "") && (tagName != "param")) && (tagName != "meta")) && ((tagName != "p") || ((tagName == "p") && this.blockTagP))) && (((((tagName != "area") && (tagName != "base")) && ((tagName != "br") && (tagName != "col"))) && (((tagName != "frame") && (tagName != "img")) && ((tagName != "input") && (tagName != "link")))) && ((((tagName != "meta") && (tagName != "basefont")) && ((tagName != "isindex") && (tagName != "hr"))) && (tagName != "script"))))
                    {
                        element2 = element;
                    }
                }
                num4 = index + 1;
            }
            goto Label_0038;
        }

        private void f6()
        {
            this.f7(this.Q);
            this.Q = "";
        }

        private void f7(string G0)
        {
            this.html = "";
            this.childElements.Clear();
            try
            {
                this.f8(HtmlDocumentState.Browsing);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(G0);
                request.KeepAlive = false;
                request.ContentType = "text/html";
                request.UserAgent = "DevComponents.com HtmlDocument Object";
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                this.html = new StreamReader(response.GetResponseStream()).ReadToEnd();
                this.f8(HtmlDocumentState.Parsing);
                this.parsehtml();
            }
            finally
            {
                this.f8(HtmlDocumentState.Ready);
            }
        }

        private void f8(HtmlDocumentState H0)
        {
            if (this.state != H0)
            {
                this.state = H0;
                if (this.K != null)
                {
                    this.K(this, new EventArgs());
                }
            }
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }

        public void Load(string filename)
        {
            StreamReader reader = new StreamReader(filename, Encoding.Default);
            reader.BaseStream.Seek(0L, SeekOrigin.Begin);
            reader.BaseStream.Position = 0L;
            this.html = reader.ReadToEnd();
            reader.DiscardBufferedData();
            reader.Close();
            this.parsehtml();
        }

        public void LoadUrl(string url)
        {
            this.LoadUrl(url, false);
        }

        public void LoadUrl(string url, bool asynchronous)
        {
            if (asynchronous)
            {
                Thread thread = new Thread(new ThreadStart(this.f6));
                this.Q = url;
                this.f8(HtmlDocumentState.Browsing);
                thread.Start();
            }
            else
            {
                this.f7(url);
            }
        }

        public override string ToString()
        {
            string str = "";
            foreach (HtmlElement2 element in this.childElements)
            {
                str = str + element.InnerHTML;
            }
            return str;
        }

        public XmlDocument ToXMLDocument()
        {
            if (this.childElements.Count > 1)
            {
                XmlDocument document = new XmlDocument();
                XmlElement newChild = document.CreateElement("htmldocument");
                document.AppendChild(newChild);
                foreach (HtmlElement2 element2 in this.childElements)
                {
                    element2.B(newChild);
                }
                return document;
            }
            if (this.childElements.Count == 1)
            {
                return ((HtmlElement2)this.childElements[0]).ToXMLDocument();
            }
            return null;
        }

        // Properties
        [Browsable(true), DefaultValue(false)]
        public bool BlockTagP
        {
            get
            {
                return this.blockTagP;
            }
            set
            {
                this.blockTagP = value;
            }
        }

        public ArrayList ChildElements
        {
            get
            {
                return this.childElements;
            }
        }

        public string Html
        {
            get
            {
                return this.html;
            }
            set
            {
                this.html = value;
                this.parsehtml();
            }
        }

        public HtmlDocumentState State
        {
            get
            {
                return this.state;
            }
        }
    }

}

 
 
